package com.example.alipay.controller;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.domain.*;
import com.example.alipay.common.PayUtil;
import com.example.alipay.config.AlipayConfig;
import com.example.alipay.entity.AlipayConfigPo;
import com.example.alipay.entity.Goods;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @author: mtl
 * @Date: 2022/3/8 14:38
 * @Description:
 */
@Slf4j
@RestController("alipay")
public class AliPayController {

    @Autowired
    AlipayConfig alipayConfig;

    /**
     * 面对面扫码支付
     * @param param
     * @return
     */
    @GetMapping("/alipay/pay")
    @ResponseBody
    public byte[] alipay(Goods param){
        Goods po = new Goods();
        po.setGoodsName("收购乌克兰")
                .setMoney("0.1")
                .setOrderSize("1")
                .setUserId("admin")
                .setOrderNumber(IdUtil.fastSimpleUUID());
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        // 自定义订单号
        model.setOutTradeNo(po.getOrderNumber());
        // 支付金额
        model.setTotalAmount(po.getMoney());
        // 支付的产品名称
        model.setSubject(po.getGoodsName());
        // 支付的请求体参数
        model.setBody(JSONObject.toJSONString(po));
        // 支付的超时时间
        model.setTimeoutExpress("30m");
        // 支付的库存id
        model.setStoreId(po.getUserId());

        AlipayConfigPo AlipayConfigPo = new AlipayConfigPo();
        BeanUtils.copyProperties(alipayConfig,AlipayConfigPo);
        return PayUtil.aliTwoDimensionalBarcodePayment(model,AlipayConfigPo);
    }

    /**
     * h5/微信公众号等支付
     * @return
     */
    @GetMapping("/alipay/paycs")
    @ResponseBody
    public String aliH5Pay(){
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        String userId = "user111";
        // 5：支付宝携带的参数在回调中可以通过request获取
        JSONObject json = new JSONObject();
        json.put("userId", userId);
        json.put("orderNumber", "Order"+snowflake.nextId());
        json.put("money", "10");
        json.put("ptype","productcourse");// 支付类型
        json.put("courseId","CpId"+snowflake.nextId());
        String params = json.toString();
        model.setOutTradeNo(String.valueOf(snowflake.nextId())); // 自定义订单号
        model.setTotalAmount("10");// 支付金额
        model.setSubject("半凡");// 支付的产品名称
        model.setBody(params);// 支付的请求体参数
        model.setTimeoutExpress("30m");// 支付的超时时间
        model.setStoreId(userId+"");// 支付的库存id

        AlipayConfigPo AlipayConfigPo = new AlipayConfigPo();
        BeanUtils.copyProperties(alipayConfig,AlipayConfigPo);
        return PayUtil.aliH5Pay(model, AlipayConfigPo);
    }

    /**
     * 退款
     * @return
     */
    @GetMapping("/alipay/refund")
    @ResponseBody
    public String aliRefund(){

        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        String outRequestNo = "Refund"+snowflake.nextId();
        log.info("-->:"+outRequestNo);
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
//        model.setOutTradeNo("Order1404357514652422144");
        model.setTradeNo("2021061522001476010500983675");
        model.setOutRequestNo(outRequestNo);
        model.setRefundAmount("10");
        model.setRefundReason("商品退款");
        AlipayConfigPo AlipayConfigPo = new AlipayConfigPo();
        BeanUtils.copyProperties(alipayConfig,AlipayConfigPo);
        return PayUtil.aliRefund(model, AlipayConfigPo);
    }

    /**
     * 退款查询
     * @return
     */
    @GetMapping("/alipay/refundQuery")
    @ResponseBody
    public String aliRefundQuery(){
        AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();
//        model.setOutTradeNo("Order1404357514652422144");
        model.setTradeNo("2021061522001476010500983675");
        model.setOutRequestNo("Refund1404683092916047872");
        AlipayConfigPo AlipayConfigPo = new AlipayConfigPo();
        BeanUtils.copyProperties(alipayConfig,AlipayConfigPo);
        return PayUtil.aliRefundQuery(model, AlipayConfigPo);
    }

    /**
     * 支付订单查询
     * @return
     */
    @GetMapping("/alipay/query")
    @ResponseBody
    public String aliQuery(){
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        model.setOutTradeNo("Order1501077622120124416");
        model.setTradeNo("1501077622204010496");
        AlipayConfigPo AlipayConfigPo = new AlipayConfigPo();
        BeanUtils.copyProperties(alipayConfig,AlipayConfigPo);
        return PayUtil.aliQuery(model, AlipayConfigPo);
    }

    /**
     * 定义支付回调的地址
     *
     * 1：第一步：打成一个jar 发布正式服务器
     * 2：第二步：购买一个域名：https:/www.kuangstudy.com/
     * 3：第三步：部署的项目到服务器上。java -jar ksd-alipay.jar >>1.txt &
     * 4：第四步：获取真实的回调地址  https:/www.kuangstudy.com/alipay/notifyUrl?body=&param&
     */
    @ResponseBody
    @RequestMapping("/alipay/notifyUrl")
    public String notify_url(HttpServletRequest request) throws Exception {
        // 1: 调用支付回调
        boolean result = alipayCallback(request);
        if (result) {
            return "success"; // 请不要修改或删除
        } else {
            // 验证失败
            return "fail";
        }
    }


    private boolean alipayCallback(HttpServletRequest request) throws UnsupportedEncodingException {
        // 1:获取支付宝GET过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        log.info("-->requestParams:"+requestParams);
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, new String(valueStr.getBytes("ISO-8859-1"), "UTF-8"));
        }

        //2：计算得出通知验证结果
        log.info("1：---->获取支付宝回传的参数---------------------------------->" + params);
        // 返回公共参数
        String tradeno = params.get("trade_no");;
        //支付返回的请求参数body
        String bodyJson = params.get("body");
        log.info("3---->:【支付宝】交易的参数信息是：{}，流水号是：{}", bodyJson, tradeno);
        try {
            JSONObject bodyJsonObject = JSONObject.parseObject(bodyJson);
            log.info("---->:bodyJsonObject", bodyJsonObject);
            String userId = bodyJsonObject.getString("userId");
            String ptype = bodyJsonObject.getString("ptype");
            String orderNumber = bodyJsonObject.getString("orderNumber");
            log.info("4---->:【支付宝】交易的参数信息是：ptype:{}，orderNumber是：{}",  ptype,orderNumber);
            // 支付成功，保存订单交易明细(核心是tradeno流水号，后续退款用)
            return true;
        } catch (Exception ex) {
            log.info("支付宝支付出现了异常.....");
            ex.printStackTrace();
            return false;
        }
    }


}
